/*
 * JerboView.java
 */

package jerbo;

import java.beans.PropertyVetoException;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.view.JasperViewer;
import org.jdesktop.application.Application;

/**
 * The application's main frame.
 */
public class JerboView extends FrameView {

    public JerboView(SingleFrameApplication app) {
        super(app);

        initComponents();

        // status bar initialization - message timeout, idle icon and busy animation, etc
        ResourceMap resourceMap = getResourceMap();
        int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
        messageTimer = new Timer(messageTimeout, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                statusMessageLabel.setText("");
            }
        });
        messageTimer.setRepeats(false);
        int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
        for (int i = 0; i < busyIcons.length; i++) {
            busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
        }
        busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
                statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
            }
        });
        idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
        statusAnimationLabel.setIcon(idleIcon);
        progressBar.setVisible(false);

        // connecting action tasks to status bar via TaskMonitor
        TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
        taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                String propertyName = evt.getPropertyName();
                if ("started".equals(propertyName)) {
                    if (!busyIconTimer.isRunning()) {
                        statusAnimationLabel.setIcon(busyIcons[0]);
                        busyIconIndex = 0;
                        busyIconTimer.start();
                    }
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(true);
                } else if ("done".equals(propertyName)) {
                    busyIconTimer.stop();
                    statusAnimationLabel.setIcon(idleIcon);
                    progressBar.setVisible(false);
                    progressBar.setValue(0);
                } else if ("message".equals(propertyName)) {
                    String text = (String)(evt.getNewValue());
                    statusMessageLabel.setText((text == null) ? "" : text);
                    messageTimer.restart();
                } else if ("progress".equals(propertyName)) {
                    int value = (Integer)(evt.getNewValue());
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(false);
                    progressBar.setValue(value);
                }
            }
        });
    }

    @Action
    public void showAboutBox() {
        if (aboutBox == null) {
            JFrame mainFrame = JerboApp.getApplication().getMainFrame();
            aboutBox = new JerboAboutBox(mainFrame);
            aboutBox.setLocationRelativeTo(mainFrame);
        }
        JerboApp.getApplication().show(aboutBox);
    }
    
    @Action
    public void showArticles() {
        try {
            boolean max = false;
            if (articlesFrame == null) {
                articlesFrame = new JerboArticles();
                mainPanel.add(articlesFrame);
                max = true;
                if (journalBox != null)
                    articlesFrame.asArticleEventSource().addArticleListener(journalBox);
            }
            articlesFrame.setVisible(true);
            if (max)
                articlesFrame.setMaximum(true);
            articlesFrame.toFront();
        } catch (PropertyVetoException ex) {
            Logger.getLogger(JerboView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    @Action
    public void showSuppliers(){
        try {
            boolean max = false;
            if (suppliersFrame == null) {
                suppliersFrame = new JerboSuppliers();
                mainPanel.add(suppliersFrame);
                max = true;
            }
            suppliersFrame.setVisible(true);
            if (max)
                suppliersFrame.setMaximum(true);
            suppliersFrame.toFront();
        } catch (PropertyVetoException ex) {
            Logger.getLogger(JerboView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    @Action
    public void showJournal(){
        if (journalBox == null) {
            JFrame mainFrame = JerboApp.getApplication().getMainFrame();
            journalBox = new JerboJournal(mainFrame);
            journalBox.setLocationRelativeTo(mainFrame);
            if (articlesFrame != null)
                articlesFrame.asArticleEventSource().addArticleListener(journalBox);
        }
        JerboApp.getApplication().show(journalBox);
    }
    
    @Action
    public void showJournalReport(){
        if (journalReportBox == null) {
            JFrame mainFrame = JerboApp.getApplication().getMainFrame();
            journalReportBox = new JerboJournalReport(mainFrame);
            journalReportBox.setLocationRelativeTo(mainFrame);
        }
        JerboApp.getApplication().show(journalReportBox);
    }
    
    
    /**
     * 
     */
    @Action
    public void showStockReport() {
        
        String reportSource =  JerboJournalReport.class.getResource(
                "/jerbo/reports/StockReport.jrxml").toString();
        
        reportSource = reportSource.substring(5);
        
        Map<String, Object> params = new HashMap<String, Object>();
        
        try {
            
            File file = new File(reportSource);

            if (file.exists()) {
            
                JasperReport jasperReport = 
                        JasperCompileManager.compileReport(reportSource);

                java.sql.Connection conn = Application.getInstance(
                        jerbo.JerboApp.class).getConnection();

                // Replace the empty JR datasource parameter with
                // the connection parameter named conn.
                JasperPrint jasperPrint =
                    JasperFillManager.fillReport(jasperReport, params, conn);

                JasperExportManager.exportReportToPdf(jasperPrint);

                JasperViewer.viewReport(jasperPrint, false);
            }
            
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(JerboView.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(JerboView.class.getName()).log(Level.SEVERE, null, ex);
        } catch (JRException ex) {
            Logger.getLogger(JerboView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu fileMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        adminMenu = new javax.swing.JMenu();
        articlesMenuItem = new javax.swing.JMenuItem();
        suppliersMenuItem = new javax.swing.JMenuItem();
        journalMenuItem = new javax.swing.JMenuItem();
        reportsMenu = new javax.swing.JMenu();
        printJournalMenuItem = new javax.swing.JMenuItem();
        printStockJournal = new javax.swing.JMenuItem();
        javax.swing.JMenu helpMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
        statusPanel = new javax.swing.JPanel();
        javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
        statusMessageLabel = new javax.swing.JLabel();
        statusAnimationLabel = new javax.swing.JLabel();
        progressBar = new javax.swing.JProgressBar();
        mainPanel = new javax.swing.JDesktopPane();

        menuBar.setName("menuBar"); // NOI18N

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(jerbo.JerboApp.class).getContext().getResourceMap(JerboView.class);
        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
        fileMenu.setName("fileMenu"); // NOI18N

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(jerbo.JerboApp.class).getContext().getActionMap(JerboView.class, this);
        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setText(resourceMap.getString("exitMenuItem.text")); // NOI18N
        exitMenuItem.setToolTipText(resourceMap.getString("exitMenuItem.toolTipText")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        adminMenu.setText(resourceMap.getString("adminMenu.text")); // NOI18N
        adminMenu.setName("adminMenu"); // NOI18N

        articlesMenuItem.setAction(actionMap.get("showArticles")); // NOI18N
        articlesMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F5, 0));
        articlesMenuItem.setText(resourceMap.getString("articlesMenuItem.text")); // NOI18N
        articlesMenuItem.setName("articlesMenuItem"); // NOI18N
        adminMenu.add(articlesMenuItem);

        suppliersMenuItem.setAction(actionMap.get("showSuppliers")); // NOI18N
        suppliersMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F6, 0));
        suppliersMenuItem.setText(resourceMap.getString("suppliersMenuItem.text")); // NOI18N
        suppliersMenuItem.setName("suppliersMenuItem"); // NOI18N
        adminMenu.add(suppliersMenuItem);

        journalMenuItem.setAction(actionMap.get("showJournal")); // NOI18N
        journalMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F7, 0));
        journalMenuItem.setText(resourceMap.getString("journalMenuItem.text")); // NOI18N
        journalMenuItem.setName("journalMenuItem"); // NOI18N
        adminMenu.add(journalMenuItem);

        menuBar.add(adminMenu);

        reportsMenu.setText(resourceMap.getString("reportsMenu.text")); // NOI18N
        reportsMenu.setName("reportsMenu"); // NOI18N

        printJournalMenuItem.setAction(actionMap.get("showJournalReport")); // NOI18N
        printJournalMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_G, java.awt.event.InputEvent.CTRL_MASK));
        printJournalMenuItem.setText(resourceMap.getString("printJournalMenuItem.text")); // NOI18N
        printJournalMenuItem.setName("printJournalMenuItem"); // NOI18N
        reportsMenu.add(printJournalMenuItem);

        printStockJournal.setAction(actionMap.get("showStockReport")); // NOI18N
        printStockJournal.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_M, java.awt.event.InputEvent.CTRL_MASK));
        printStockJournal.setText(resourceMap.getString("printStockJournal.text")); // NOI18N
        printStockJournal.setName("printStockJournal"); // NOI18N
        reportsMenu.add(printStockJournal);

        menuBar.add(reportsMenu);

        helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
        helpMenu.setName("helpMenu"); // NOI18N

        aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
        aboutMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_I, java.awt.event.InputEvent.CTRL_MASK));
        aboutMenuItem.setName("aboutMenuItem"); // NOI18N
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        statusPanel.setName("statusPanel"); // NOI18N

        statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N

        statusMessageLabel.setName("statusMessageLabel"); // NOI18N

        statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N

        progressBar.setName("progressBar"); // NOI18N

        org.jdesktop.layout.GroupLayout statusPanelLayout = new org.jdesktop.layout.GroupLayout(statusPanel);
        statusPanel.setLayout(statusPanelLayout);
        statusPanelLayout.setHorizontalGroup(
            statusPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(statusPanelSeparator, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
            .add(statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(statusMessageLabel)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 216, Short.MAX_VALUE)
                .add(progressBar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(statusAnimationLabel)
                .addContainerGap())
        );
        statusPanelLayout.setVerticalGroup(
            statusPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(statusPanelLayout.createSequentialGroup()
                .add(statusPanelSeparator, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .add(statusPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(statusMessageLabel)
                    .add(statusAnimationLabel)
                    .add(progressBar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(3, 3, 3))
        );

        mainPanel.setBackground(resourceMap.getColor("mainPanel.background")); // NOI18N
        mainPanel.setName("mainPanel"); // NOI18N

        setComponent(mainPanel);
        setMenuBar(menuBar);
        setStatusBar(statusPanel);
    }// </editor-fold>//GEN-END:initComponents

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenu adminMenu;
    private javax.swing.JMenuItem articlesMenuItem;
    private javax.swing.JMenuItem journalMenuItem;
    private javax.swing.JDesktopPane mainPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenuItem printJournalMenuItem;
    private javax.swing.JMenuItem printStockJournal;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JMenu reportsMenu;
    private javax.swing.JLabel statusAnimationLabel;
    private javax.swing.JLabel statusMessageLabel;
    private javax.swing.JPanel statusPanel;
    private javax.swing.JMenuItem suppliersMenuItem;
    // End of variables declaration//GEN-END:variables
    
    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;

    private JDialog aboutBox;
    private jerbo.JerboJournal journalBox;
    private JDialog journalReportBox;
    
    private jerbo.JerboArticles articlesFrame;
    private JInternalFrame suppliersFrame;
    
}
